package com.youlu.campus.service.wechat.impl;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.common.utils.RedisKeyUtil;
import com.youlu.campus.entity.VO.req.WechatAuthBlackListQueryVO;
import com.youlu.campus.entity.WechatAuthBlackList;
import com.youlu.campus.service.wechat.WechatAuthBlackListService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class WechatAuthBlackListServiceImpl implements WechatAuthBlackListService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Page<WechatAuthBlackList> list(WechatAuthBlackListQueryVO req) {
        Query query = new Query();
        query.addCriteria(Criteria.where("deleted").ne(Boolean.TRUE));
        if (StringUtils.isNotBlank(req.getSysName())) {
            query.addCriteria(Criteria.where("sysName").is(req.getSysName()));
        }
        if (StringUtils.isNotBlank(req.getType())) {
            query.addCriteria(Criteria.where("type").is(req.getType()));
        }
        if (StringUtils.isNotBlank(req.getSysAppId())) {
            query.addCriteria(Criteria.where("sysAppId").is(req.getSysAppId()));
        }
        long count = this.mongoTemplate.count(query, WechatAuthBlackList.class);
        PageRequest pageRequest = PageRequest.of(req.getPage() - 1, req.getPageSize());
        if (count == 0) {
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> count);
        }
//        query.with(new Sort(Sort.Direction.DESC, "createdTime"));
        Sort sort = Sort.by(Sort.Direction.DESC, "createdTime");
        query.with(sort);
        query.with(pageRequest);
        List<WechatAuthBlackList> list = this.mongoTemplate.find(query, WechatAuthBlackList.class);
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    @Override
    public boolean create(@NotNull WechatAuthBlackList data) {
        data.setId(null);
        data.setCreatedTime(new Date());
        data = mongoTemplate.insert(data);
        deleteCache(data.getSysAppId());
        if (Objects.isNull(data.getId())) {
            return true;
        }
        return false;
    }

    @Override
    public boolean update(WechatAuthBlackList data) {
        WechatAuthBlackList old = mongoTemplate.findById(data.getId(), WechatAuthBlackList.class);
        if (Objects.isNull(old)) {
            return false;
        }
        if (StringUtils.isNotBlank(data.getSysAppId())) {
            old.setSysAppId(data.getSysAppId());
        }
        if (StringUtils.isNotBlank(data.getSecret())) {
            old.setSecret(data.getSecret());
        }
        if (StringUtils.isNotBlank(data.getType())) {
            old.setType(data.getType());
        }
        if (StringUtils.isNotBlank(data.getSysName())) {
            old.setSysName(data.getSysName());
        }
        if (StringUtils.isNotBlank(data.getDefaultAppId())) {
            old.setDefaultAppId(data.getDefaultAppId());
        }
        if (Objects.nonNull(data.getBlackLists()) && !CollectionUtils.isEmpty(data.getBlackLists())) {
            old.setBlackLists(data.getBlackLists());
        }
        if (Objects.nonNull(data.getIpWhiteList()) && !CollectionUtils.isEmpty(data.getIpWhiteList())) {
            old.setIpWhiteList(data.getIpWhiteList());
        }
        if (StringUtils.isNotBlank(data.getDesc())) {
            old.setDesc(data.getDesc());
        }
        old.setUpdatedTime(new Date());
        mongoTemplate.save(old);
        deleteCache(old.getSysAppId());
        return true;
    }

    @Override
    public WechatAuthBlackList findOne(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        return mongoTemplate.findOne(query, WechatAuthBlackList.class);
    }

    @Override
    public boolean delete(String id) {
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        Update update = new Update();
        update.set("deleted", true);
        update.set("updatedTime", new Date());
        UpdateResult updateResult = mongoTemplate.updateFirst(query, update, WechatAuthBlackList.class);
        return updateResult.getModifiedCount() > 0 ? true : false;
    }

    @Override
    public WechatAuthBlackList findBySysAppId(String sysAppId) {
        String key = RedisKeyUtil.getWechatBlackListKey(sysAppId);
        String s = redisTemplate.opsForValue().get(key);
        if (StringUtils.isNotBlank(s)) {
            return JSONObject.parseObject(s, WechatAuthBlackList.class);
        }
        Query query = new Query();
        query.addCriteria(Criteria.where("sysAppId").is(sysAppId));
        WechatAuthBlackList one = mongoTemplate.findOne(query, WechatAuthBlackList.class);
        redisTemplate.opsForValue().set(key, JSONObject.toJSONString(one), 3, TimeUnit.DAYS);
        return one;
    }

    private void deleteCache(String sysAppId) {
        if (StringUtils.isBlank(sysAppId)) {
            return;
        }
        String key = RedisKeyUtil.getWechatBlackListKey(sysAppId);
        redisTemplate.delete(key);
    }
}
